package model

import (
	"go.mongodb.org/mongo-driver/bson/primitive"
)

// userid  UIDBASE | UID << UID_BIT | GAME_ID   例 UID_BASE | UID(1) << 4 | GAMEID(1)
// 可用uid范围为 1 ~2,147,483,632
// 游戏id占用最后4位 最多支持15种游戏
const (
	BASE_BIT = 31
	UID_BIT  = 4
	UID_BASE = 1 << BASE_BIT
)

type Gender int

const (
	GenderUnknown Gender = iota // 未知
	GenderMale                  // 男性
	GenderFemale                // 女性
)

// Type 用户类型
type Type int

const (
	TypeRobot   Type = 0 // 机器人用户
	TypeGuest   Type = 1 // 游客用户
	TypeGeneral Type = 2 // 普通用户
	TypeSystem  Type = 3 // 系统用户
)

// Status 用户状态
type Status int

const (
	StatusNormal    Status = iota // 正常
	StatusForbidden               // 封禁
)

// 封禁类型
type BanType int

const (
	BanType_Login BanType = iota + 1 // 封号
	BanType_Match                    // 禁赛
)

type WechatInfo struct {
	Nickname string `json:"nickname" form:"nickname"`
	Avatar   string `json:"avatar" form:"avatar"`
	Gender   int32  `json:"gender" form:"gender"`
}

// ThirdPlatforms 第三方平台
type ThirdPlatforms struct {
	Wechat   string `bson:"wechat"`
	Google   string `bson:"google"`
	Facebook string `bson:"facebook"`
}

type Currency struct {
	Id    int32   `bson:"id" json:"id"`
	Count float64 `bson:"count" json:"count"`
}

type Ticket struct {
	Id        int32               `bson:"id" json:"id"`
	Count     float64             `bson:"count" json:"count"`
	ExpireT   *primitive.DateTime `bson:"expire_t" json:"expire_t"`
	GoodsStat GoodsStat           `bson:"goods_stat" json:"goods_stat"`
	Limit     int32               `bson:"limit" json:"limit"`
}

type Item struct {
	Id    int32   `bson:"id" json:"id"`
	Count float64 `bson:"count" json:"count"`
}

type GameStat struct {
	Type   int32 `bson:"type" json:"type"`     // 游戏类型
	Win    int32 `bson:"win" json:"win"`       // 胜利次数
	Lose   int32 `bson:"lose" json:"lose"`     // 失败次数
	Escape int32 `bson:"escape" json:"escape"` // 逃跑次数
}

type GameToday struct {
	Sharing     int32            `bson:"sharing" json:"sharing"`
	Recharge    int32            `bson:"recharge" json:"recharge"`
	ShopBuy     map[int32]int64  `bson:"shop_buy" json:"shop_buy"`
	BuyCost     int32            `bson:"buy_cost" json:"buy_cost"`
	ItemConvert map[int32]int64  `bson:"item_convert" json:"item_convert"`
	Today       int64            `bson:"today" json:"today"` // 今日时间戳
	Product     map[string]int32 `bson:"product" json:"product"`
	VipDaily    int32            `bson:"vip_daily" json:"vip_daily"` // vip 每日礼包 当前领取的等级
}

type ActivityStat struct {
	ActId int32              `bson:"act_id" json:"act_id"`
	Info  interface{}        `bson:"info" json:"info"`
	CTime primitive.DateTime `bson:"c_time" json:"c_time"`
}

type Pack struct {
	ID         int32               `bson:"id" json:"id"`
	BuyTime    *primitive.DateTime `bson:"buy_time" json:"buy_time"`
	LastTime   *primitive.DateTime `bson:"last_time" json:"last_time"` // 上次领取
	ExpireTime *primitive.DateTime `bson:"expire_time" json:"expire_time"`
	Remain     *int32              `bson:"remain" json:"remain"` // 剩余时间
}

type BankPack struct {
	ID      int32               `bson:"id" json:"id"`
	BuyTime *primitive.DateTime `bson:"buy_time" json:"buy_time"`
	//LastTime   *primitive.DateTime `bson:"last_time" json:"last_time"` // 上次领取
	//ExpireTime *primitive.DateTime `bson:"expire_time" json:"expire_time"`
	Remain int32 `bson:"remain" json:"remain"` // 剩余时间
}

type Vip struct {
	Level      int32               `bson:"level" json:"level"`           // 等级
	Experience int64               `bson:"experience" json:"experience"` // 经验值
	Product    []string            `bson:"product" json:"product"`       // 已购买的等级礼包
	LifeBonus  []int32             `bson:"life_bonus" json:"life_bonus"` // 终身领取
	Packs      []Pack              `bson:"packs" json:"packs"`
	LastTime   *primitive.DateTime `bson:"last_time" json:"last_time"` // 最后
}
type Bank struct {
	LastCheckTime *primitive.DateTime `bson:"last_check_time" json:"last_check_time"` //上次检测的时间
	Packs         []BankPack          `bson:"packs" json:"packs"`
}

type Recharge struct {
	FirstTime   *primitive.DateTime `bson:"first_time" json:"first_time"`     // 第一次充值日期
	LastTime    *primitive.DateTime `bson:"last_time" json:"last_time"`       // 上次充值日期
	TotalAmount int64               `bson:"total_amount" json:"total_amount"` // 合计充值
	LastAmount  int64               `bson:"last_amount" json:"last_amount"`   //  上次充值
}

type Ban struct {
	ExpireTime *primitive.DateTime `bson:"expire_time" json:"expire_time"`
	Reason     string              `bson:"reason" json:"reason"`
	CTime      primitive.DateTime  `bson:"c_time" json:"c_time"`
	BanType    BanType             `bson:"ban_type" json:"ban_type"` // 0
}

type IDCard struct {
	CardNo string             `bson:"card_no" json:"card_no"`
	Name   string             `bson:"name" json:"name"`
	CTime  primitive.DateTime `bson:"c_time" json:"c_time"`
}

type Credit struct {
	Score       int32              `bson:"score" json:"score"`
	LastT       primitive.DateTime `bson:"timestamp" json:"timestamp"`     // 上次扣除时间
	ShareT      primitive.DateTime `bson:"share_t" json:"share_t"`         // 上次通过分享游戏获得信誉分时间
	Appointment CreditRecord       `bson:"appointment" json:"appointment"` // 好友约局获得信誉分
	Training    CreditRecord       `bson:"training" json:"training"`       // 训练场获得信誉分
}

type CreditRecord struct {
	Count int64              `bson:"count" json:"count"`         // 获得到信誉分的次数
	LastT primitive.DateTime `bson:"timestamp" json:"timestamp"` // 上次获得的时间
}

type MScore struct {
	Score int64 `bson:"score" json:"score"`
}

type Active struct {
	Value int64 `bson:"value" json:"value"`
	Week  int32 `bson:"week" json:"week"`
}

type GoodsStat struct {
	Goods     map[int32]int64 `bson:"goods" json:"goods"`
	TotalCost int32           `bson:"total" json:"total"`
}
type RewardGetTime struct {
	Stair int32              `bson:"stair" json:"stair"`
	Time  primitive.DateTime `bson:"time" json:"time"`
}

type SeriesLogin struct {
	Count int32              `bson:"count" json:"count"`         // 连续登录天数
	LastT primitive.DateTime `bson:"timestamp" json:"timestamp"` // 上次操作修改时间
}

type Task struct {
	TaskId       int32              `bson:"task_id" json:"task_id"`             //任务ID
	CreateTime   primitive.DateTime `bson:"create_time" json:"create_time"`     //创建时间
	Progress     int32              `bson:"progress" json:"progress"`           //提交次数
	ReceiveTimes int32              `bson:"receive_times" json:"receive_times"` //已领取过的次数
	Date         int32              `bson:"date" json:"date"`                   //按任务类型 分为第几周 或第几天
	IsDone       bool               `bson:"is_done" json:"is_done"`             // 是否已完成
}

type ChannelFPCurrency struct {
	WalletTypeId  int32 `bson:"walletTypeId" json:"walletTypeId"`   //币种类型，
	WalletIncome  int64 `bson:"walletIncome" json:"walletIncome"`   //总收⼊额
	WalletOutcome int64 `bson:"walletOutcome" json:"walletOutcome"` //总支出额
	BalanceFee    int64 `bson:"balanceFee" json:"balanceFee"`       //可用额
}

// 首席体验官信息
type ExpOfficeData struct {
	Type     int32 `bson:"type" json:"type"` //0关闭 1开启 2被淘汰
	AllTimes int32 `bson:"all_times" json:"all_times"`
}

// 摇钱树
type MyTree struct {
	ItemId    int32               `bson:"item_id" json:"item_id"`
	StartTime *primitive.DateTime `bson:"start_time" json:"start_time"`
	EndTime   *primitive.DateTime `bson:"end_time" json:"end_time"`
	Timestamp *primitive.DateTime `bson:"timestamp" json:"timestamp"` // 上次领取时间
}
type FriendTree struct {
	UID       int64               `bson:"friend_id" json:"friend_id"`
	TreeId    int32               `bson:"tree_id" json:"tree_id"`
	StartTime *primitive.DateTime `bson:"start_time" json:"start_time"`
	EndTime   *primitive.DateTime `bson:"end_time" json:"end_time"`
	Timestamp *primitive.DateTime `bson:"timestamp" json:"timestamp"` // 上次领取时间
}

type GoldTree struct {
	Trees       []*MyTree     `bson:"trees" json:"trees"`
	FriendTrees []*FriendTree `bson:"friend_trees" json:"friend_trees"`
}

type Strategy struct {
	Limit int64 `bson:"limit" json:"limit"`
	Count int64 `bson:"count" json:"count"` // 本次获得的金币数
}

//go:generate mongo-dao-generator -model-dir=. -model-names=User -dao-dir=../../dao/user
type User struct {
	ID               primitive.ObjectID  `bson:"_id" json:"-" gen:"autoFill"`
	UID              int64               `bson:"uid" json:"uid" gen:"autoIncr:uid"` // 用户ID
	Account          string              `bson:"account" json:"account"`            // 用户账号
	Password         string              `bson:"password" json:"-"`                 // 用户密码
	Salt             string              `bson:"salt" json:"-"`                     // 密码
	UnionID          string              `bson:"unionid" json:"-"`                  // 微信授权用户唯一标识
	LoginType        int32               `bson:"login_type" json:"-"`               // 本次登陆类型
	WechatOpenID     string              `bson:"wechat_open_id" json:"-"`
	WechatMiniOpenID string              `bson:"wechat_mini_open_id" json:"-"`                 //
	WechatWebOpenID  string              `bson:"wechat_web_open_id" json:"-"`                  //
	Mobile           string              `bson:"mobile" json:"mobile"`                         // 用户手机
	Email            string              `bson:"email" json:"email"`                           // 用户邮箱
	Nickname         string              `bson:"nickname" json:"nickname"`                     // 用户昵称
	Avatar           string              `bson:"avatar" json:"avatar"`                         // 用户头像
	Signature        string              `bson:"signature" json:"signature"`                   // 用户签名
	Gender           int32               `bson:"gender" json:"gender"`                         // 用户性别
	Level            int32               `bson:"level" json:"level"`                           // 用户等级
	Experience       int32               `bson:"experience" json:"experience"`                 // 用户经验
	Credit           Credit              `bson:"credit" json:"credit"`                         // 被扣除的
	InvitedCode      int64               `bson:"invited_code" json:"invited_code"`             // 我填写的邀请码
	MyUnion          int64               `bson:"my_union" json:"my_union"`                     // 联盟ID
	LastQuitUnionId  int64               `bson:"last_quit_union_id" json:"last_quit_union_id"` // 上一次退出的联盟ID
	UnionInvite      []int64             `bson:"union_invite" json:"union_invite"`             // 工会邀请
	LastQuitUnion    *primitive.DateTime `bson:"last_quit_union" json:"last_quit_union"`       // 上次退出联盟
	NewUnionInvite   int32               `bson:"new_union_invite" json:"new_union_invite"`     // 新的俱乐部邀请
	TeamId           int64               `bson:"team_id" json:"team_id"`                       // 战队ID
	TeamInvite       []int64             `bson:"team_invite" json:"team_invite"`               // 战队邀请
	NewTeamInvite    int32               `bson:"new_team_invite" json:"new_team_invite"`       // 新的俱乐部邀请
	LastQuitTeam     *primitive.DateTime `bson:"last_quit_team" json:"last_quit_team"`         // 上次退出战队
	PromotionCode    int64               `bson:"promotion_code" json:"promotion_code"`         // 推广码
	Vip              Vip                 `bson:"vip" json:"vip"`                               // 用户vip
	Bank             *Bank               `bson:"bank" json:"bank"`                             //银行
	Recharge         Recharge            `bson:"recharge" json:"recharge"`                     // 充值数据
	Currency         []Currency          `bson:"currency" json:"currency"`                     // 用户货币
	Items            []Item              `bson:"items" json:"-"`                               // 道具
	GameStats        []GameStat          `bson:"game_stats" json:"-"`                          // 统计数据
	GameToday        *GameToday          `bson:"game_today" json:"-"`                          // 今日数据统计
	ActivityStats    []ActivityStat      `bson:"activity_stats" json:"-"`                      // 活动统计
	GoodsStat        *GoodsStat          `bson:"goods_stat" json:"-"`                          // 商品统计
	IDCard           *IDCard             `bson:"id_card" json:"-"`                             // 身份信息
	Type             Type                `bson:"type" json:"type"`                             // 用户类型
	// Address             commonmodel.AddrList `bson:"address" json:"address"`                                // 地址
	Ban                 Ban                 `bson:"ban" json:"ban"`                                        // 封禁数据
	ThirdPlatforms      ThirdPlatforms      `bson:"third_platforms" json:"third_platforms"`                // 第三方平台
	LastPlatform        string              `bson:"last_platform" json:"last_platform"`                    // 上次登录平台
	RegisterChannel     int32               `bson:"register_channel" json:"register_channel"`              // 注册渠道
	RegisterDevice      string              `bson:"register_device" json:"register_device"`                // 注册设备
	RegisterDeviceID    string              `bson:"register_device_id" json:"register_device_id"`          // 注册设备ID
	RegisterIP          string              `bson:"register_ip" json:"-"`                                  // 注册IP
	RegisterTime        primitive.DateTime  `bson:"register_time" json:"register_time" gen:"autoFill"`     // 注册时间
	LastLoginIP         string              `bson:"last_login_ip" json:"last_login_ip"`                    // 最近登录IP
	LastLoginChannel    int32               `bson:"last_login_channel" json:"last_login_channel"`          // 最近登录渠道
	LoginTime           primitive.DateTime  `bson:"login_time" json:"login_time" gen:"autoFill"`           // 本次登录时间
	LastLoginTime       primitive.DateTime  `bson:"last_login_time" json:"last_login_time" gen:"autoFill"` // 上次登录时间
	IsRobot             bool                `bson:"is_robot" json:"is_robot"  gen:"autoFill"`              //机器人登陆判断
	IsDistribute        bool                `bson:"is_distribute" json:"is_distribute"`                    // 是否为团长
	DistributeLevel     int32               `bson:"distribute_level" json:"distribute_level"`              // 团长等级
	DistributeDate      *primitive.DateTime `bson:"distribute_date" json:"distribute_date"`                // 成为团长时间
	CanSendLog          bool                `bson:"can_send_log" json:"can_send_log"`                      // 用户是否可以发送日志文件
	SendLogDate         int64               `bson:"send_log_date" json:"send_log_date"`                    // 用户是否可以发送日志文件
	Location            Location            `bson:"location" json:"location"`                              // 修改昵称次数
	IsPromotion         bool                `bson:"is_promotion" json:"is_promotion"`
	ModifyNicknameTimes int32               `bson:"modify_nickname_times" json:"modify_nickname_times"` // 修改昵称次数
	ModifyAvatarTimes   int32               `bson:"modify_avatar_times" json:"modify_avatar_times"`     // 修改头像次数
	Tasks               []*Task             `bson:"tasks" json:"tasks"`                                 // 任务相关
	SeriesLogin         SeriesLogin         `bson:"series_login" json:"series_login"`                   // 连续登录天数
	AccLoginCount       int32               `bson:"acc_login_count" json:"acc_login_count"`             // 累计登录次数
	Strategy            Strategy            `bson:"strategy" json:"strategy"`
	Guide               string              `bson:"guide" json:"guide"`                     // 引导
	NoviceStrategy      int32               `bson:"novice_strategy" json:"novice_strategy"` // 新手策略路线
	//第三方绑定相关信息
	ChannelGameID     int32              `bson:"channel_game_id" json:"channel_game_id"` //第三方游戏id
	ChannelId         int32              `bson:"channel_id" json:"channel_id"`           //渠道channelID
	ChannelToken      string             `bson:"channel_token" json:"channel_token"`     //渠道token
	ChannelUID        int64              `bson:"channel_uid" json:"channel_uid"`         //渠道游戏用户id
	ChannelUIDString  string             `bson:"channel_uid_string" json:"channel_uid_string"`
	ChannelFPCurrency *ChannelFPCurrency `bson:"channel_fp_currency" json:"channel_fp_currency"` //渠道货币
	ExpOfficeData     *ExpOfficeData     `bson:"ExpOfficeData" json:"ExpOfficeData"`
	BankSaveBet       int64              `bson:"bank_save_bet" json:"bank_save_bet"` //存储的bet
	GoldTree          *GoldTree          `bson:"gold_tree" json:"gold_tree"`         // 用户货币
	Ticket            []Ticket           `bson:"ticket" json:"ticket"`
	RealFlag          int32              `bson:"real_flag" json:"real_flag"`

	DTime *primitive.DateTime `bson:"d_time" json:"d_time"` //删除日志
}

func (u *Pack) GetRemain() int32 {
	if u.Remain != nil {
		return *u.Remain
	}
	return -1
}

func (u *Pack) SetRemain(n int32) {
	u.Remain = &n
}

func (u *Pack) AddRemain(n int32) {
	*u.Remain += n
}

// ParseToClient
// 参数: self bool  标记是否展示自身（自身将展示更多数据）
// 作用: 把用户数据库数据转化成客户端需要展示的数据
// func (u *User) ParseToClient(self bool) *common.User {
// 	// 计算胜率
// 	winRate := []*common.WinRate{}
// 	for _, v := range u.GameStats {
// 		total := v.Win + v.Lose
// 		rate := fmt.Sprintf("%.2f", float32(v.Win)/float32(total))

// 		winRate = append(winRate, &common.WinRate{
// 			Game:   v.Type,
// 			Rate:   rate,
// 			Win:    v.Win,
// 			Lose:   v.Lose,
// 			Escape: v.Escape,
// 		})
// 	}

// 	var userInfo = new(common.User)
// 	userInfo.ShowID = u.UID
// 	userInfo.Nickname = u.Nickname
// 	userInfo.Avatar = u.Avatar
// 	userInfo.Signature = u.Signature
// 	userInfo.Gender = u.Gender
// 	userInfo.Level = u.Level
// 	userInfo.WinRate = winRate
// 	userInfo.LastLoginIP = u.LastLoginIP
// 	userInfo.LastLoginTime = u.LoginTime.Time().Unix()
// 	userInfo.MyUnion = u.MyUnion
// 	userInfo.ModifyNicknameTimes = u.ModifyNicknameTimes

// 	userInfo.IDCard = &common.IDCard{}
// 	userInfo.Mobile = u.Mobile
// 	userInfo.IDCardCheck = config.Get("config.environment.IDCardCheck", false).Bool()
// 	userInfo.Guide = u.Guide
// 	userInfo.CTime = u.RegisterTime.Time().UnixMilli()
// 	userInfo.ChannelUID = u.ChannelUID
// 	if u.IDCard != nil {
// 		userInfo.IDCard.CardNo = u.IDCard.CardNo
// 		userInfo.IDCard.Name = u.IDCard.Name
// 		userInfo.IDCard.CTime = u.IDCard.CTime.Time().UnixMilli()
// 	}
// 	if u.ChannelFPCurrency != nil {
// 		if userInfo.ChannelFPCurrency == nil {
// 			userInfo.ChannelFPCurrency = new(common.ChannelFPCurrency)
// 		}

// 		userInfo.ChannelFPCurrency.BalanceFee = u.ChannelFPCurrency.BalanceFee
// 		userInfo.ChannelFPCurrency.WalletTypeId = u.ChannelFPCurrency.WalletTypeId
// 	}

// 	userInfo.Vip = new(common.Vip)
// 	userInfo.Vip.Level = u.Vip.Level
// 	userInfo.Vip.Experience = u.Vip.Experience

// 	userInfo.Vip.Packs = make([]*common.Pack, 0)
// 	vipPack, _, expireT := u.GetMaxLvVipPack()
// 	if vipPack != nil {
// 		userInfo.Vip.Packs = []*common.Pack{
// 			{
// 				ID:         vipPack.ID,
// 				ExpireTime: expireT.Time().UnixMilli(),
// 			},
// 		}
// 	}

// 	if self {
// 		items := []*common.Item{}
// 		for _, v := range u.Items {
// 			if v.Count > 0 {
// 				items = append(items, &common.Item{
// 					Id:    v.Id,
// 					Count: v.Count,
// 				})
// 			}
// 		}

// 		currency := []*common.Item{}
// 		for _, v := range u.Currency {
// 			currency = append(currency, &common.Item{
// 				Id:    v.Id,
// 				Count: v.Count,
// 			})
// 		}

// 		userInfo.Addresses = new(common.Addresses)
// 		userInfo.Addresses.Index = u.Address.DefIndex
// 		addresses := []*common.Address{}
// 		for _, v := range u.Address.List {
// 			addresses = append(addresses, &common.Address{
// 				Name:   v.Name,
// 				Phone:  v.Phone,
// 				Detail: v.Detail,
// 			})
// 		}
// 		userInfo.Addresses.List = addresses

// 		userInfo.UID = u.UID
// 		userInfo.Account = u.Account
// 		userInfo.Currency = currency
// 		userInfo.Items = items
// 		userInfo.Experience = u.Experience
// 		userInfo.CreditScore = u.Credit.Score
// 		userInfo.InvitedCode = u.InvitedCode
// 		userInfo.RealFlag = u.RealFlag
// 	}

// 	return userInfo
// }

func (u *User) CountGameTimes(ty int32) int32 {
	var count int32
	for _, v := range u.GameStats {
		if v.Type == ty || ty == 0 {
			count += v.Win
			count += v.Lose
			count += v.Escape
		}
	}
	return count
}

func (u *User) CountItemById(itemId int32) float64 {
	var count float64

	for _, v := range u.Items {
		if v.Id == itemId {
			count = v.Count
			break
		}
	}
	return count
}

func (u *User) CountCurrencyById(currencyId int32) float64 {
	var count float64

	for _, v := range u.Currency {
		if v.Id == currencyId {
			count = v.Count
			break
		}
	}
	return count
}

// func (u *User) CheckVipExist(rechargeId int32) bool {
// 	packs := u.Vip.Packs
// 	for _, v := range packs {
// 		if rechargeId == v.ID {
// 			diffDay := utils.DiffDays(u.LoginTime.Time(), time.Now())
// 			if v.Remain != nil && *v.Remain-int32(diffDay) > 0 {
// 				return true
// 			}
// 		}
// 	}
// 	return false
// }

// func (u *User) GetMaxLvVipPack() (*Pack, int, primitive.DateTime) {
// 	var maxLvPack *Pack
// 	var index = -1
// 	for k, v := range u.Vip.Packs {
// 		if maxLvPack == nil {
// 			maxLvPack = &u.Vip.Packs[k]
// 			index = k
// 		} else {
// 			if gbase.GameChargeMap[v.ID].CostTimeNum < gbase.GameChargeMap[maxLvPack.ID].CostTimeNum {
// 				maxLvPack = &u.Vip.Packs[k]
// 				index = k
// 			}
// 		}
// 	}

// 	var expireTime primitive.DateTime
// 	if maxLvPack != nil {
// 		expireStamp, _ := utils.SetDayTime("23:59:59", int64(maxLvPack.GetRemain())*24*60*60*1000)
// 		expireTime = primitive.DateTime(expireStamp)
// 	}

// 	return maxLvPack, index, expireTime
// }

func (u *User) GetTicketById(ticketId int32) *Ticket {
	var ticket *Ticket
	for _, v := range u.Ticket {
		if v.Id == ticketId {
			ticket = &v
			break
		}
	}

	return ticket
}

func (u *User) GetNowTaskIds() []int32 {
	var taskIds = []int32{}
	for _, v := range u.Tasks {
		taskIds = append(taskIds, v.TaskId)
	}
	return taskIds
}

func (u *User) GetTaskById(taskId int32) *Task {
	for _, v := range u.Tasks {
		if v.TaskId == taskId {
			return v
		}
	}
	return nil
}

